package com.vhall.component.plugin.common.utils;

import cn.hutool.core.date.DatePattern;
import com.vhall.component.plugin.common.annotation.CheckTimeInterval;
import com.vhall.component.plugin.common.constant.ConstStr;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.LocalDateTime;

/**
 * 时间范围校验器
 *
 * @author kainan.li
 */
public class CheckTimeIntervalValidator implements ConstraintValidator<CheckTimeInterval, Object> {
    private String startTime;
    private String endTime;
    private boolean equal;

    @Override
    public void initialize(CheckTimeInterval constraintAnnotation) {
        this.startTime = constraintAnnotation.startTime();
        this.endTime = constraintAnnotation.endTime();
        this.equal = constraintAnnotation.equal();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(value);
        String startStr = (String) beanWrapper.getPropertyValue(startTime);
        String endStr = (String) beanWrapper.getPropertyValue(endTime);
        if (StringUtils.isAllBlank(startStr, endStr)) {
            return true;
        }
        context.disableDefaultConstraintViolation();
        LocalDateTime start = parse(startStr, context, true);
        if (StringUtils.isNotBlank(startStr) && start == null) {
            return false;
        }
        LocalDateTime end = parse(endStr, context, false);
        if (StringUtils.isNotBlank(endStr) && end == null) {
            return false;
        }
        if (start == null || end == null) {
            //校验格式完成
            return true;
        }
        if (equal) {
            context.buildConstraintViolationWithTemplate("开始时间:" + startStr + "不能晚于结束时间:" + endStr)
                    .addConstraintViolation();
            return start.isEqual(end) || start.isBefore(end);
        } else {
            context.buildConstraintViolationWithTemplate("开始时间:" + startStr + "不能晚于或等于结束时间:" + endStr)
                    .addConstraintViolation();
            return start.isBefore(end);
        }
    }

    private LocalDateTime parse(String date, ConstraintValidatorContext context, boolean start) {
        LocalDateTime ldt;
        try {
            ldt = LocalDateTime.parse(date, DatePattern.NORM_DATETIME_FORMATTER);
        } catch (Exception e) {
            try {
                ldt = LocalDateTime.parse(date + " " + ConstStr.TIME_ZERO, DatePattern.NORM_DATETIME_FORMATTER);
            } catch (Exception e1) {
                if (start) {
                    context.buildConstraintViolationWithTemplate("开始时间:" + date + "格式有误")
                            .addConstraintViolation();
                } else {
                    context.buildConstraintViolationWithTemplate("结束时间:" + date + "格式有误")
                            .addConstraintViolation();
                }
                return null;
            }
        }
        return ldt;
    }

}
